package com.shuidihuzhu.sdb.helper.log.matter;

import com.shuidihuzhu.sdb.helper.log.LogFur;
import com.shuidihuzhu.sdb.helper.log.annotation.LogMethodInvoke;
import com.shuidihuzhu.sdb.helper.log.utils.JsonUtil;
import com.shuidihuzhu.sdb.helper.log.utils.KeyWordsUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.lang.reflect.Method;

/**
 * 日志输出方法调用事件
 * @author dongzhihua
 */
public class LogMethodInvokeMatter implements LogFur<LogMethodInvoke> {
    @Override
    public void before(Method method, Object param, LogMethodInvoke annotation) {
        if (method.getParameterCount() == 1) {
            if (param == null) {
                log(method, null, annotation, "开始");
            } else {
                log(method, ((Object[]) param)[0], annotation, "开始");
            }
        } else {
            log(method, param, annotation, "开始");
        }
    }

    @Override
    public void after(Method method, Object result, LogMethodInvoke annotation) {
        log(method, result, annotation, "结束");
    }

    @Override
    public Class<LogMethodInvoke> getType() {
        return LogMethodInvoke.class;
    }

    /**
     * 输出日志
     * @param method 方法
     * @param obj 日志输出对象
     * @param annotation 类上注解
     * @param flag 标识 开始/结束
     */
    private void log(Method method, Object obj, LogMethodInvoke annotation, String flag) {

        if (method == null || annotation == null) {
            return;
        }

        final Logger log = LoggerFactory.getLogger(method.getDeclaringClass());
        final String json = JsonUtil.toJsonDesc(obj);
        String kw = annotation.keyWords();
        if (!StringUtils.hasText(kw)) {
            kw = KeyWordsUtil.kw(method);
        }

        switch (annotation.level()) {
            case "DEBUG" : log.debug("{} {} {}", kw, flag, json); break;
            case "WARN" : log.warn("{} {} {}", kw, flag, json); break;
            case "ERROR" : log.error("{} {} {}", kw, flag, json); break;
            default: log.info("{} {} {}", kw, flag, json);
        }
    }
}
